package com.kan.awaits;

import java.util.HashMap;

import javax.sql.DataSource;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.kan.awaits.exception.MappingException;
import com.kan.awaits.exception.ORMException;

public class Configuration
{
	private static Log logger = LogFactory.getLog(Configuration.class);

	private DataSource dataSource;

	private SQLDialect dialect;// SQL方言

	private HashMap<Class<?>, TableMeta<?>> ts = new HashMap<Class<?>, TableMeta<?>>();

	private SessionFactory sessionFactory;

	private boolean runtimeMapping = false;// 运行时映射,如果开启这个,用户不需在程序初始化的时候addClass,又需要的时候程序会自动加载映射信息

	public SessionFactory buildSessionFactory() throws ORMException
	{
		if (dataSource == null)
		{
			throw new ORMException("Can not build sessonFactory, Cause:the datasource not bean set");
		}
		if (sessionFactory == null)
			sessionFactory = new SessionFactory(dataSource, ts);
		return sessionFactory;
	}

	public Configuration setDataSource(DataSource dataSource)
	{
		this.dataSource = dataSource;
		return this;
	}

	/**
	 * 
	 * @param persistentClass
	 * @return
	 * @throws MappingException
	 */
	public TableMeta<?> getTableMeta(Class<?> persistentClass) throws MappingException
	{
		TableMeta<?> tableMeta = ts.get(persistentClass);
		if (tableMeta == null && runtimeMapping)
		{
			this.addClass(persistentClass);
			tableMeta = ts.get(persistentClass);
		}
		return tableMeta;
	}

	public Configuration reomveClass(Class<?> persistentClass) throws MappingException
	{
		ts.remove(persistentClass);
		logger.info("Reading mappings from resource: " + persistentClass);
		return this;
	}

	public Configuration addClass(Class<?> persistentClass) throws MappingException
	{
		TableMeta<?> tableMeta = TableMeta.getTableMeta(persistentClass);

		// logger.debug("\n" + tableMeta.getDDL());
		ts.put(persistentClass, tableMeta);
		logger.info("Reading mappings from resource: " + persistentClass);
		return this;
	}
}
